from rest_framework import serializers
from rest_framework.exceptions import ValidationError

from AKapi.settings.dev import RETURN_URL, NOTIFY_URL
from . import models


class OrderSerializer(serializers.ModelSerializer):
    # 规定前端传过来的数据:{course:[1, 2, 3], total_amount:100, subject:xx商品,pay_type:1}
    # 需要吧course:[1, 2, 3] ---> course:[obj1, obj2, obj3]
    # user字段需要，但不是穿的，使用了jwt
    # course = serializers.CharField()
    course = serializers.PrimaryKeyRelatedField(queryset=models.Course.objects.all(), write_only=True, many=True, required=True)
                                                #  queryset表示course字段跟哪个表做关联

    # 反序列化
    class Meta:
        model = models.Order
        fields = ['total_amount', 'subject', 'pay_type', 'course']
        extra_kwargs = {
            'total_amount': {'required': True},
            'pay_type': {'required': True},
        }

    def _check_price(self, attrs: dict):
        total_amount = attrs.get('total_amount')
        course_list = attrs.get('course')
        print(total_amount, type(total_amount))
        total_price = 0
        for course in course_list:
            total_price += course.price
        if total_price != total_amount:
            raise ValidationError('价格不合法')
        return total_amount

    def _gen_out_trade_no(self):
        import uuid
        return str(uuid.uuid4()).replace('-', '')

    def _before_create(self, attrs: dict, user, pay_url, out_trade_no):
        attrs['user'] = user
        attrs['out_trade_no'] = out_trade_no
        self.context['pay_url'] = pay_url

    def _get_user(self):
        """
        需要request对象，需要视图通过context把request对象传入，重写create方法
        :return:
        """
        request = self.context.get('request')
        return request.user

    def _gen_pay_url(self, out_trade_no, total_amount, subject):
        from AKapi.libs.al_pay import alipay, gateway
        order_string = alipay.api_alipay_trade_page_pay(
            out_trade_no=out_trade_no,
            total_amount=float(total_amount),
            subject=subject,
            return_url=RETURN_URL,  # get同步回调(前台回调)
            notify_url=NOTIFY_URL  # post回调(后台地址)
        )
        print(gateway + order_string)
        return gateway + order_string

    def validate(self, attrs: dict):
        """
        订单总价校验
        生成订单号
        支付用户request.user
        支付链接生成
        入库(两个表)的信息准备
        :param attrs:
        :return:
        """
        total_amount = self._check_price(attrs)  # 订单总价校验
        out_trade_no = self._gen_out_trade_no()  # 生成订单号
        user = self._get_user()  # 支付用户request.user
        pay_url = self._gen_pay_url(out_trade_no, total_amount, attrs.get('subject'))  # 支付链接生成
        self._before_create(attrs, user, pay_url, out_trade_no)
        return attrs

    def create(self, validated_data):
        print(validated_data)
        course_list = validated_data.pop('course')
        order = models.Order.objects.create(**validated_data)
        for course in course_list:
            models.OrderDetail.objects.create(order=order, price=course.price, real_price=course.price, course=course)
        return order
